module chip;

import arm.misc:CmpVal;
import std.traits : isAutodecodableString;
import std.meta : allSatisfy;
import baremetal;
import arm.cortex_m4;



enum TargetChips = GetConfig!("TargetChips");
enum SVDWidth = GetConfig!("SVDWidth");
enum pIm1 = CmpVal!(TargetChips,"stm32f401cc");



//imported!("stm32f401cc");
/*
pragma(msg,pIm1);
static if(pIm1 == true){
    public import chip.stm32f401cc;
    
    
}
*/
/// 导入芯片定义
public{
    version(STM32F401CC) import chip.stm32f401cc;
}




/**
* 获取配置信息
* Params:
*   op = `ChipConfig`中的配置名称
*/
template GetConfig(string op)
{
    import chipconf;
    static if(__traits(hasMember,ChipConfig, op)){
        enum GetConfig = __traits(getMember, ChipConfig,op);
    }else{
        enum GetConfig = false;
    }
}


/// 生成向量表
//enum VectorFunc[] Cortex_Mx = Cortex_M ~ Cortex_M4[Isr_Ext.min .. $];

enum VectorFunc[] Cortex_Mx = Cortex_M ~ Cortex_M4;
@isr_vector extern(C) immutable VectorFunc[Cortex_Mx.length] CortexM_Isr = cast(immutable VectorFunc[])Cortex_Mx;


/**
* 判定是否拥有对应的外设
* Params:
*   T = 外设名称,支持字符串及字符串数组
*/
template HasPeriph(T...) if (allSatisfy!(isAutodecodableString, typeof(T)) )
{
    import chip.stm32f401;
    static if(T.length > 1){
        enum HasPeriph = __traits(hasMember, Peripherals, T[0]) || HasPeriph!(T[1..$]);
    }else{
        enum HasPeriph = __traits(hasMember, Peripherals, T[0]);
    }
}




//------------
/*
    调试用:测试当前编译器支持的特性
*/
version(none){
    pragma(msg,"mcu_32bit\t:",__traits(targetHasFeature,"32bit"));
    pragma(msg,"mcu_8msecext\t:",__traits(targetHasFeature,"8msecext"));
    pragma(msg,"mcu_a12\t:",__traits(targetHasFeature,"a12"));
    pragma(msg,"mcu_a15\t:",__traits(targetHasFeature,"a15"));
    pragma(msg,"mcu_a17\t:",__traits(targetHasFeature,"a17"));
    pragma(msg,"mcu_a32\t:",__traits(targetHasFeature,"a32"));
    pragma(msg,"mcu_a35\t:",__traits(targetHasFeature,"a35"));
    pragma(msg,"mcu_a5\t:",__traits(targetHasFeature,"a5"));
    pragma(msg,"mcu_a53\t:",__traits(targetHasFeature,"a53"));
    pragma(msg,"mcu_a55\t:",__traits(targetHasFeature,"a55"));
    pragma(msg,"mcu_a57\t:",__traits(targetHasFeature,"a57"));
    pragma(msg,"mcu_a7\t:",__traits(targetHasFeature,"a7"));
    pragma(msg,"mcu_a72\t:",__traits(targetHasFeature,"a72"));
    pragma(msg,"mcu_a73\t:",__traits(targetHasFeature,"a73"));
    pragma(msg,"mcu_a75\t:",__traits(targetHasFeature,"a75"));
    pragma(msg,"mcu_a76\t:",__traits(targetHasFeature,"a76"));
    pragma(msg,"mcu_a77\t:",__traits(targetHasFeature,"a77"));
    pragma(msg,"mcu_a8\t:",__traits(targetHasFeature,"a8"));
    pragma(msg,"mcu_a9\t:",__traits(targetHasFeature,"a9"));
    pragma(msg,"mcu_aclass\t:",__traits(targetHasFeature,"aclass"));
    pragma(msg,"mcu_acquire-release\t:",__traits(targetHasFeature,"acquire-release"));
    pragma(msg,"mcu_aes\t:",__traits(targetHasFeature,"aes"));
    pragma(msg,"mcu_armv2\t:",__traits(targetHasFeature,"armv2"));
    pragma(msg,"mcu_armv2a\t:",__traits(targetHasFeature,"armv2a"));
    pragma(msg,"mcu_armv3\t:",__traits(targetHasFeature,"armv3"));
    pragma(msg,"mcu_armv3m\t:",__traits(targetHasFeature,"armv3m"));
    pragma(msg,"mcu_armv4\t:",__traits(targetHasFeature,"armv4"));
    pragma(msg,"mcu_armv4t\t:",__traits(targetHasFeature,"armv4t"));
    pragma(msg,"mcu_armv5t\t:",__traits(targetHasFeature,"armv5t"));
    pragma(msg,"mcu_armv5te\t:",__traits(targetHasFeature,"armv5te"));
    pragma(msg,"mcu_armv5tej\t:",__traits(targetHasFeature,"armv5tej"));
    pragma(msg,"mcu_armv6\t:",__traits(targetHasFeature,"armv6"));
    pragma(msg,"mcu_armv6-m\t:",__traits(targetHasFeature,"armv6-m"));
    pragma(msg,"mcu_armv6j\t:",__traits(targetHasFeature,"armv6j"));
    pragma(msg,"mcu_armv6k\t:",__traits(targetHasFeature,"armv6k"));
    pragma(msg,"mcu_armv6kz\t:",__traits(targetHasFeature,"armv6kz"));
    pragma(msg,"mcu_armv6s-m\t:",__traits(targetHasFeature,"armv6s-m"));
    pragma(msg,"mcu_armv6t2\t:",__traits(targetHasFeature,"armv6t2"));
    pragma(msg,"mcu_armv7-a\t:",__traits(targetHasFeature,"armv7-a"));
    pragma(msg,"mcu_armv7-m\t:",__traits(targetHasFeature,"armv7-m"));
    pragma(msg,"mcu_armv7-r\t:",__traits(targetHasFeature,"armv7-r"));
    pragma(msg,"mcu_armv7e-m\t:",__traits(targetHasFeature,"armv7e-m"));
    pragma(msg,"mcu_armv7k\t:",__traits(targetHasFeature,"armv7k"));
    pragma(msg,"mcu_armv7s\t:",__traits(targetHasFeature,"armv7s"));
    pragma(msg,"mcu_armv7ve\t:",__traits(targetHasFeature,"armv7ve"));
    pragma(msg,"mcu_armv8-a\t:",__traits(targetHasFeature,"armv8-a"));
    pragma(msg,"mcu_armv8-m.base\t:",__traits(targetHasFeature,"armv8-m.base"));
    pragma(msg,"mcu_armv8-m.main\t:",__traits(targetHasFeature,"armv8-m.main"));
    pragma(msg,"mcu_armv8-r\t:",__traits(targetHasFeature,"armv8-r"));
    pragma(msg,"mcu_armv8.1-a\t:",__traits(targetHasFeature,"armv8.1-a"));
    pragma(msg,"mcu_armv8.1-m.main\t:",__traits(targetHasFeature,"armv8.1-m.main"));
    pragma(msg,"mcu_armv8.2-a\t:",__traits(targetHasFeature,"armv8.2-a"));
    pragma(msg,"mcu_armv8.3-a\t:",__traits(targetHasFeature,"armv8.3-a"));
    pragma(msg,"mcu_armv8.4-a\t:",__traits(targetHasFeature,"armv8.4-a"));
    pragma(msg,"mcu_armv8.5-a\t:",__traits(targetHasFeature,"armv8.5-a"));
    pragma(msg,"mcu_armv8.6-a\t:",__traits(targetHasFeature,"armv8.6-a"));
    pragma(msg,"mcu_avoid-movs-shop\t:",__traits(targetHasFeature,"avoid-movs-shop"));
    pragma(msg,"mcu_avoid-partial-cpsr\t:",__traits(targetHasFeature,"avoid-partial-cpsr"));
    pragma(msg,"mcu_bf16\t:",__traits(targetHasFeature,"bf16"));
    pragma(msg,"mcu_cde\t:",__traits(targetHasFeature,"cde"));
    pragma(msg,"mcu_cdecp0\t:",__traits(targetHasFeature,"cdecp0"));
    pragma(msg,"mcu_cdecp1\t:",__traits(targetHasFeature,"cdecp1"));
    pragma(msg,"mcu_cdecp2\t:",__traits(targetHasFeature,"cdecp2"));
    pragma(msg,"mcu_cdecp3\t:",__traits(targetHasFeature,"cdecp3"));
    pragma(msg,"mcu_cdecp4\t:",__traits(targetHasFeature,"cdecp4"));
    pragma(msg,"mcu_cdecp5\t:",__traits(targetHasFeature,"cdecp5"));
    pragma(msg,"mcu_cdecp6\t:",__traits(targetHasFeature,"cdecp6"));
    pragma(msg,"mcu_cdecp7\t:",__traits(targetHasFeature,"cdecp7"));
    pragma(msg,"mcu_cheap-predicable-cpsr\t:",__traits(targetHasFeature,"cheap-predicable-cpsr"));
    pragma(msg,"mcu_cortex-a78\t:",__traits(targetHasFeature,"cortex-a78"));
    pragma(msg,"mcu_cortex-x1\t:",__traits(targetHasFeature,"cortex-x1"));
    pragma(msg,"mcu_crc\t:",__traits(targetHasFeature,"crc"));
    pragma(msg,"mcu_crypto\t:",__traits(targetHasFeature,"crypto"));
    pragma(msg,"mcu_d32\t:",__traits(targetHasFeature,"d32"));
    pragma(msg,"mcu_db\t:",__traits(targetHasFeature,"db"));
    pragma(msg,"mcu_dfb\t:",__traits(targetHasFeature,"dfb"));
    pragma(msg,"mcu_disable-postra-scheduler\t:",__traits(targetHasFeature,"disable-postra-scheduler"));
    pragma(msg,"mcu_dont-widen-vmovs\t:",__traits(targetHasFeature,"dont-widen-vmovs"));
    pragma(msg,"mcu_dotprod\t:",__traits(targetHasFeature,"dotprod"));
    pragma(msg,"mcu_dsp\t:",__traits(targetHasFeature,"dsp"));
    pragma(msg,"mcu_execute-only\t:",__traits(targetHasFeature,"execute-only"));
    pragma(msg,"mcu_expand-fp-mlx\t:",__traits(targetHasFeature,"expand-fp-mlx"));
    pragma(msg,"mcu_exynos\t:",__traits(targetHasFeature,"exynos"));
    pragma(msg,"mcu_fp-armv8\t:",__traits(targetHasFeature,"fp-armv8"));
    pragma(msg,"mcu_fp-armv8d16\t:",__traits(targetHasFeature,"fp-armv8d16"));
    pragma(msg,"mcu_fp-armv8d16sp\t:",__traits(targetHasFeature,"fp-armv8d16sp"));
    pragma(msg,"mcu_fp-armv8sp\t:",__traits(targetHasFeature,"fp-armv8sp"));
    pragma(msg,"mcu_fp16\t:",__traits(targetHasFeature,"fp16"));
    pragma(msg,"mcu_fp16fml\t:",__traits(targetHasFeature,"fp16fml"));
    pragma(msg,"mcu_fp64\t:",__traits(targetHasFeature,"fp64"));
    pragma(msg,"mcu_fpao\t:",__traits(targetHasFeature,"fpao"));
    pragma(msg,"mcu_fpregs\t:",__traits(targetHasFeature,"fpregs"));
    pragma(msg,"mcu_fpregs16\t:",__traits(targetHasFeature,"fpregs16"));
    pragma(msg,"mcu_fpregs64\t:",__traits(targetHasFeature,"fpregs64"));
    pragma(msg,"mcu_fullfp16\t:",__traits(targetHasFeature,"fullfp16"));
    pragma(msg,"mcu_fuse-aes\t:",__traits(targetHasFeature,"fuse-aes"));
    pragma(msg,"mcu_fuse-literals\t:",__traits(targetHasFeature,"fuse-literals"));
    pragma(msg,"mcu_hwdiv\t:",__traits(targetHasFeature,"hwdiv"));
    pragma(msg,"mcu_hwdiv-arm\t:",__traits(targetHasFeature,"hwdiv-arm"));
    pragma(msg,"mcu_i8mm\t:",__traits(targetHasFeature,"i8mm"));
    pragma(msg,"mcu_iwmmxt\t:",__traits(targetHasFeature,"iwmmxt"));
    pragma(msg,"mcu_iwmmxt2\t:",__traits(targetHasFeature,"iwmmxt2"));
    pragma(msg,"mcu_krait\t:",__traits(targetHasFeature,"krait"));
    pragma(msg,"mcu_kryo\t:",__traits(targetHasFeature,"kryo"));
    pragma(msg,"mcu_lob\t:",__traits(targetHasFeature,"lob"));
    pragma(msg,"mcu_long-calls\t:",__traits(targetHasFeature,"long-calls"));
    pragma(msg,"mcu_loop-align\t:",__traits(targetHasFeature,"loop-align"));
    pragma(msg,"mcu_m3\t:",__traits(targetHasFeature,"m3"));
    pragma(msg,"mcu_mclass\t:",__traits(targetHasFeature,"mclass"));
    pragma(msg,"mcu_mp\t:",__traits(targetHasFeature,"mp"));
    pragma(msg,"mcu_muxed-units\t:",__traits(targetHasFeature,"muxed-units"));
    pragma(msg,"mcu_mve\t:",__traits(targetHasFeature,"mve"));
    pragma(msg,"mcu_mve.fp\t:",__traits(targetHasFeature,"mve.fp"));
    pragma(msg,"mcu_mve1beat\t:",__traits(targetHasFeature,"mve1beat"));
    pragma(msg,"mcu_mve2beat\t:",__traits(targetHasFeature,"mve2beat"));
    pragma(msg,"mcu_mve4beat\t:",__traits(targetHasFeature,"mve4beat"));
    pragma(msg,"mcu_nacl-trap\t:",__traits(targetHasFeature,"nacl-trap"));
    pragma(msg,"mcu_neon\t:",__traits(targetHasFeature,"neon"));
    pragma(msg,"mcu_neon-fpmovs\t:",__traits(targetHasFeature,"neon-fpmovs"));
    pragma(msg,"mcu_neonfp\t:",__traits(targetHasFeature,"neonfp"));
    pragma(msg,"mcu_no-branch-predictor\t:",__traits(targetHasFeature,"no-branch-predictor"));
    pragma(msg,"mcu_no-movt\t:",__traits(targetHasFeature,"no-movt"));
    pragma(msg,"mcu_no-neg-immediates\t:",__traits(targetHasFeature,"no-neg-immediates"));
    pragma(msg,"mcu_noarm\t:",__traits(targetHasFeature,"noarm"));
    pragma(msg,"mcu_nonpipelined-vfp\t:",__traits(targetHasFeature,"nonpipelined-vfp"));
    pragma(msg,"mcu_perfmon\t:",__traits(targetHasFeature,"perfmon"));
    pragma(msg,"mcu_prefer-ishst\t:",__traits(targetHasFeature,"prefer-ishst"));
    pragma(msg,"mcu_prefer-vmovsr\t:",__traits(targetHasFeature,"prefer-vmovsr"));
    pragma(msg,"mcu_prof-unpr\t:",__traits(targetHasFeature,"prof-unpr"));
    pragma(msg,"mcu_r4\t:",__traits(targetHasFeature,"r4"));
    pragma(msg,"mcu_r5\t:",__traits(targetHasFeature,"r5"));
    pragma(msg,"mcu_r52\t:",__traits(targetHasFeature,"r52"));
    pragma(msg,"mcu_r7\t:",__traits(targetHasFeature,"r7"));
    pragma(msg,"mcu_ras\t:",__traits(targetHasFeature,"ras"));
    pragma(msg,"mcu_rclass\t:",__traits(targetHasFeature,"rclass"));
    pragma(msg,"mcu_read-tp-hard\t:",__traits(targetHasFeature,"read-tp-hard"));
    pragma(msg,"mcu_reserve-r9\t:",__traits(targetHasFeature,"reserve-r9"));
    pragma(msg,"mcu_ret-addr-stack\t:",__traits(targetHasFeature,"ret-addr-stack"));
    pragma(msg,"mcu_sb\t:",__traits(targetHasFeature,"sb"));
    pragma(msg,"mcu_sha2\t:",__traits(targetHasFeature,"sha2"));
    pragma(msg,"mcu_slow-fp-brcc\t:",__traits(targetHasFeature,"slow-fp-brcc"));
    pragma(msg,"mcu_slow-load-D-subreg\t:",__traits(targetHasFeature,"slow-load-D-subreg"));
    pragma(msg,"mcu_slow-odd-reg\t:",__traits(targetHasFeature,"slow-odd-reg"));
    pragma(msg,"mcu_slow-vdup32\t:",__traits(targetHasFeature,"slow-vdup32"));
    pragma(msg,"mcu_slow-vgetlni32\t:",__traits(targetHasFeature,"slow-vgetlni32"));
    pragma(msg,"mcu_slowfpvfmx\t:",__traits(targetHasFeature,"slowfpvfmx"));
    pragma(msg,"mcu_slowfpvmlx\t:",__traits(targetHasFeature,"slowfpvmlx"));
    pragma(msg,"mcu_soft-float\t:",__traits(targetHasFeature,"soft-float"));
    pragma(msg,"mcu_splat-vfp-neon\t:",__traits(targetHasFeature,"splat-vfp-neon"));
    pragma(msg,"mcu_strict-align\t:",__traits(targetHasFeature,"strict-align"));
    pragma(msg,"mcu_swift\t:",__traits(targetHasFeature,"swift"));
    pragma(msg,"mcu_thumb-mode\t:",__traits(targetHasFeature,"thumb-mode"));
    pragma(msg,"mcu_thumb2\t:",__traits(targetHasFeature,"thumb2"));
    pragma(msg,"mcu_trustzone\t:",__traits(targetHasFeature,"trustzone"));
    pragma(msg,"mcu_use-misched\t:",__traits(targetHasFeature,"use-misched"));
    pragma(msg,"mcu_v4t\t:",__traits(targetHasFeature,"v4t"));
    pragma(msg,"mcu_v5t\t:",__traits(targetHasFeature,"v5t"));
    pragma(msg,"mcu_v5te\t:",__traits(targetHasFeature,"v5te"));
    pragma(msg,"mcu_v6\t:",__traits(targetHasFeature,"v6"));
    pragma(msg,"mcu_v6k\t:",__traits(targetHasFeature,"v6k"));
    pragma(msg,"mcu_v6m\t:",__traits(targetHasFeature,"v6m"));
    pragma(msg,"mcu_v6t2\t:",__traits(targetHasFeature,"v6t2"));
    pragma(msg,"mcu_v7\t:",__traits(targetHasFeature,"v7"));
    pragma(msg,"mcu_v7clrex\t:",__traits(targetHasFeature,"v7clrex"));
    pragma(msg,"mcu_v8\t:",__traits(targetHasFeature,"v8"));
    pragma(msg,"mcu_v8.1a\t:",__traits(targetHasFeature,"v8.1a"));
    pragma(msg,"mcu_v8.1m.main\t:",__traits(targetHasFeature,"v8.1m.main"));
    pragma(msg,"mcu_v8.2a\t:",__traits(targetHasFeature,"v8.2a"));
    pragma(msg,"mcu_v8.3a\t:",__traits(targetHasFeature,"v8.3a"));
    pragma(msg,"mcu_v8.4a\t:",__traits(targetHasFeature,"v8.4a"));
    pragma(msg,"mcu_v8.5a\t:",__traits(targetHasFeature,"v8.5a"));
    pragma(msg,"mcu_v8.6a\t:",__traits(targetHasFeature,"v8.6a"));
    pragma(msg,"mcu_v8m\t:",__traits(targetHasFeature,"v8m"));
    pragma(msg,"mcu_v8m.main\t:",__traits(targetHasFeature,"v8m.main"));
    pragma(msg,"mcu_vfp2\t:",__traits(targetHasFeature,"vfp2"));
    pragma(msg,"mcu_vfp2sp\t:",__traits(targetHasFeature,"vfp2sp"));
    pragma(msg,"mcu_vfp3\t:",__traits(targetHasFeature,"vfp3"));
    pragma(msg,"mcu_vfp3d16\t:",__traits(targetHasFeature,"vfp3d16"));
    pragma(msg,"mcu_vfp3d16sp\t:",__traits(targetHasFeature,"vfp3d16sp"));
    pragma(msg,"mcu_vfp3sp\t:",__traits(targetHasFeature,"vfp3sp"));
    pragma(msg,"mcu_vfp4\t:",__traits(targetHasFeature,"vfp4"));
    pragma(msg,"mcu_vfp4d16\t:",__traits(targetHasFeature,"vfp4d16"));
    pragma(msg,"mcu_vfp4d16sp\t:",__traits(targetHasFeature,"vfp4d16sp"));
    pragma(msg,"mcu_vfp4sp\t:",__traits(targetHasFeature,"vfp4sp"));
    pragma(msg,"mcu_virtualization\t:",__traits(targetHasFeature,"virtualization"));
    pragma(msg,"mcu_vldn-align\t:",__traits(targetHasFeature,"vldn-align"));
    pragma(msg,"mcu_vmlx-forwarding\t:",__traits(targetHasFeature,"vmlx-forwarding"));
    pragma(msg,"mcu_vmlx-hazards\t:",__traits(targetHasFeature,"vmlx-hazards"));
    pragma(msg,"mcu_wide-stride-vfp\t:",__traits(targetHasFeature,"wide-stride-vfp"));
    pragma(msg,"mcu_xscale\t:",__traits(targetHasFeature,"xscale"));
    pragma(msg,"mcu_zcz\t:",__traits(targetHasFeature,"zcz"));
    pragma(msg,"CPU = ", __traits(targetCPU));
    static assert(false, "Test Config");
}